home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_03 / grant / chrom.cpp < prev    next >
C/C++ Source or Header  |  1994-05-30  |  3KB  |  138 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <assert.h>
  4.  
  5. #include "chrom.h"
  6.  
  7. size_t    CGAChromosome::m_Count         = 0;
  8. size_t    CGAChromosome::m_Length        = 0;
  9. GABool*   CGAChromosome::m_CrossoverMask = 0;
  10.  
  11. // Default constructor and destructor.
  12. // Create the chromosome with bits turned on at the
  13. // given probability.
  14.  
  15. CGAChromosome::CGAChromosome(
  16.    float Prob)
  17. {
  18.    assert(m_Length);
  19.    m_Fitness  = 0;
  20.    m_Data     = new GABool[m_Length];
  21.    assert(m_Data);
  22.    m_Count++;
  23.    for (size_t Idx = 0; Idx < m_Length; Idx++) {
  24.       m_Data[Idx] = Flip(Prob);
  25.    }
  26.    m_Fitness  = CalcFitness(this);
  27. }
  28.  
  29. CGAChromosome::~CGAChromosome(void)
  30. {
  31.    delete[] m_Data;
  32.    if (--m_Count == 0) {
  33.       delete[] m_CrossoverMask;
  34.       m_Length        = 0;
  35.       m_CrossoverMask = 0;
  36.    }
  37. }
  38.  
  39. // Mutate a single chromosome gene selected at
  40. // random for a given probability.
  41.  
  42. void  CGAChromosome::Mutate(
  43.    float Prob)
  44. {
  45.    for (size_t Idx = 0; Idx < m_Length; Idx++) {
  46.       if (Flip(Prob)) {
  47.          m_Data[Idx] = !m_Data[Idx];
  48.       }
  49.    }
  50. }
  51.  
  52. // Create two new offspring using a uniform crossover
  53. // operator created with the given probability.
  54.  
  55. void Crossover(
  56.    CGAChromosome* Parent1,
  57.    CGAChromosome* Parent2,
  58.    CGAChromosome*& Child1,
  59.    CGAChromosome*& Child2,
  60.    float Prob)
  61. {
  62.    CGAChromosome::InitializeCrossoverMask(0.5);
  63.    Child1 = new CGAChromosome();
  64.    Child2 = new CGAChromosome();
  65.    assert(Child1 && Child2);
  66.  
  67.    for (size_t Idx = 0; Idx < CGAChromosome::m_Length;
  68.         Idx++) {
  69.       if (CGAChromosome::m_CrossoverMask[Idx]) {
  70.          Child1->m_Data[Idx] = Parent1->m_Data[Idx];
  71.          Child2->m_Data[Idx] = Parent2->m_Data[Idx];
  72.       } else {
  73.          Child1->m_Data[Idx] = Parent2->m_Data[Idx];
  74.          Child2->m_Data[Idx] = Parent1->m_Data[Idx];
  75.       }
  76.    }
  77.    Child1->Mutate(Prob);
  78.    Child2->Mutate(Prob);
  79.    Child1->m_Fitness = CalcFitness(Child1);
  80.    Child2->m_Fitness = CalcFitness(Child2);
  81. }
  82.  
  83. // Calculate the difference between two chromosomes
  84.  
  85. float CalcSimilarityRatio(
  86.    CGAChromosome* Chrom1,
  87.    CGAChromosome* Chrom2)
  88. {
  89.    for (size_t Idx = 0, MatchCount = 0;
  90.         Idx < CGAChromosome::m_Length; Idx++) {
  91.       if (Chrom1->m_Data[Idx] == Chrom2->m_Data[Idx]) {
  92.          MatchCount++;
  93.       }
  94.    }
  95.    return (float)MatchCount /
  96.           (float)CGAChromosome::m_Length;
  97. }
  98.  
  99. // Set the passed chromosome to the opposite encoding
  100. // of this chromosome.
  101.  
  102. CGAChromosome* CGAChromosome::Compliment(void) const
  103. {
  104.    CGAChromosome* Chromosome = new CGAChromosome;
  105.    for (size_t Idx = 0; Idx < m_Length; Idx++) {
  106.       Chromosome->m_Data[Idx] = !m_Data[Idx];
  107.    }
  108.    Chromosome->m_Fitness = CalcFitness(Chromosome);
  109.    return Chromosome;
  110. }
  111.  
  112. // Setup the crossover mask for creating the next
  113. // offspring.
  114.  
  115. void CGAChromosome::InitializeCrossoverMask(
  116.    float Prob)
  117. {
  118.    assert(m_Length && m_CrossoverMask);
  119.    for (size_t Idx = 0; Idx < m_Length; Idx++) {
  120.       m_CrossoverMask[Idx] = Flip(Prob);
  121.    }
  122. }
  123.  
  124. // Setup the chromosomes' length and allocate memory
  125. // for the crossover mask.
  126.  
  127. void CGAChromosome::InitializeChromosomeClass(
  128.    size_t Length)
  129. {
  130.    assert(Length);
  131.    m_Length = Length;
  132.    if (m_Count != 0) {
  133.       delete [] m_CrossoverMask;
  134.    }
  135.    m_CrossoverMask = new GABool[m_Length];
  136.    assert(m_CrossoverMask);
  137. }
  138.